﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using API.StoreWebService;
using DB;

namespace API
{
    public class StoreApi
    {
        private string _sessionid;
        private const string ProductType = "simple";
        private const string AttributeSetId = "9";
        private readonly StoreWebService.Mage_Api_Model_Server_V2_HandlerPortTypeClient webService;

        private static StoreApi _api;
        public static StoreApi Api
        {
            get
            {
                if (_api == null)
                {
                    _api = new StoreApi();
                }
                return _api;
            }
        }
        private StoreApi() 
        {
            webService = new StoreWebService.Mage_Api_Model_Server_V2_HandlerPortTypeClient();
            _sessionid = webService.login("alex", "yongming");
        }


        public string strErrorPoruct = "";
        public void ReSetProductImage(Product product)
        {
            try
            {

                var Images = ProductImageApi.GetImages(product);
                if (Images.Count > 0)
                {
                    var entitys = webService.catalogProductAttributeMediaList(this._sessionid, product.SKU, "0", null);
                    foreach (var catalogProductImageEntity in entitys)
                    {
                        webService.catalogProductAttributeMediaRemove(this._sessionid, product.SKU,
                                                                      catalogProductImageEntity.file, null);
                    }
                    int iPosition = 0;
                    foreach (Image image in Images)
                    {
                        if (image != null)
                        {
                            var si = webService.catalogProductAttributeMediaCreate(this._sessionid, product.SKU,
                                                                          GetcatalogProductAttributeMediaCreateEntity(
                                                                              image, iPosition++, product), "0", null);
                        }
                    }
                }
            }
            catch (Exception)
            {
                strErrorPoruct += product.SKU + "/r/n";
            }
        }
        public List<string> GetProductImageUrls(string sku)
        {
            var listRtn = new List<string>();
            try
            {
                var entitys = webService.catalogProductAttributeMediaList(this._sessionid, sku, "0", null);
                foreach (var catalogProductImageEntity in entitys)
                {
                    listRtn.Add(catalogProductImageEntity.url);
                }
            }
            catch (Exception)
            {
            }
            return listRtn;
        }
        public void UpdateProduct(Product product)
        {

            try
            {
                try
                {
                    webService.catalogProductUpdate(this._sessionid, product.SKU, GetcatalogProductCreateEntity(product), "0", null);
                }
                catch (Exception ex)
                {
                    if (ex.Message == "Product not exists.")
                        webService.catalogProductCreate(this._sessionid, ProductType, AttributeSetId, product.SKU, GetcatalogProductCreateEntity(product), "0");
                }

            }
            catch (Exception ex)
            {
                string v = ex.Message;
            }
        }

        public void UpdateProductAdditionalAttributes(string sku, string strkey, string strvalue)
        {

            try
            {
                catalogProductCreateEntity productData = new catalogProductCreateEntity();
                productData.additional_attributes = new catalogProductAdditionalAttributesEntity();
                productData.additional_attributes.single_data = new associativeEntity[] { new associativeEntity() { key = strkey, value = strvalue } };
                webService.catalogProductUpdate(this._sessionid, sku, productData, "0", null);
            }
            catch (Exception ex)
            {
                string v = ex.Message;
            }
        }

        public void UpdateProductStock(bool bInStock,string strSku)
        {
            catalogInventoryStockItemUpdateEntity stock = new catalogInventoryStockItemUpdateEntity();
            stock.manage_stock = 1;
            stock.is_in_stockSpecified = bInStock;
            stock.is_in_stock = bInStock?1:0;
            stock.qty = Convert.ToString(bInStock ? 100 : 0);
            webService.catalogInventoryStockItemUpdate(this._sessionid, strSku, stock);
        }
        public void SetProductNewest(string strSku)
        {
            UpdateProductAdditionalAttributes(strSku, "news_from_date", DateTime.Now.AddDays(-1).ToShortDateString());
            UpdateProductAdditionalAttributes(strSku, "news_to_date", DateTime.Now.AddDays(30).ToShortDateString());
        }

        public void CreateProduct(Product product)
        {

            try
            {
                webService.catalogProductCreate(this._sessionid, ProductType, AttributeSetId, product.SKU,
                                                GetcatalogProductCreateEntity(product), "0");

            }
            catch (Exception ex)
            {
                string v = ex.Message;
            }
        }
        public catalogCategoryTree GetCategory()
        {
            return webService.catalogCategoryTree(this._sessionid, "1", "0");
        }
        public void AssignProduct2Category(Alllovebling_Products_Online product,int iCategoryId)
        {
            AssignProduct2Category(product.SKU, iCategoryId);
        }
        public void AssignProduct2Category(string strSku, string[] iCategoryIds)
        {
            var productinfo = this.GetProductInfo(strSku, null);
            foreach (var iCategoryId in productinfo.categories)
            {
                if (!iCategoryIds.Contains(iCategoryId))
                {
                    RemoveProductFromCategory(strSku, Convert.ToInt32(iCategoryId));
                }
            }
            foreach (var iCategoryId in iCategoryIds)
            {
                if (string.IsNullOrEmpty(iCategoryId))continue;
                if (!productinfo.categories.Contains(iCategoryId))
                {
                    AssignProduct2Category(strSku, Convert.ToInt32(iCategoryId));
                }
            }
        }
        public void AssignProduct2Category(string strSku, int iCategoryId)
        {
            webService.catalogCategoryAssignProduct(this._sessionid, iCategoryId, strSku, "0", null);
        }

        public void RemoveProductFromCategory(string strSku, int iCategoryId)
        {
            webService.catalogCategoryRemoveProduct(this._sessionid, iCategoryId, strSku, null);
        }
        public catalogProductEntity[] GetOnlineProductList()
        {
            catalogProductEntity[] catalogProductEntitys;
            webService.catalogProductList(out catalogProductEntitys, this._sessionid, new filters(), "0");
            return catalogProductEntitys;
        }

        public catalogProductReturnEntity GetProductInfo(catalogProductEntity catalogProductEntity, string[] additionalAttributes)
        {
            return GetProductInfo(catalogProductEntity.sku, additionalAttributes);
        }
        public catalogProductReturnEntity GetProductInfo(string sku, string[] additionalAttributes)
        {
            var attr = new catalogProductRequestAttributes();
            attr.additional_attributes = additionalAttributes;
            return webService.catalogProductInfo(this._sessionid, sku, "0", attr, null);
        }
        public catalogProductAttributeSetEntity[] GetAttributeSet()
        {
            return webService.catalogProductAttributeSetList(this._sessionid);
        }

        public catalogAttributeEntity[] GetAttributelist(catalogProductAttributeSetEntity catalogProductAttributeSetEntity)
        {
            return webService.catalogProductAttributeList(this._sessionid, catalogProductAttributeSetEntity.set_id);
        }
        public catalogAttributeEntity[] GetAttributelist()
        {
            return webService.catalogProductAttributeList(this._sessionid, Convert.ToInt32(AttributeSetId));
        }

        public catalogProductAttributeEntity GetAttributeInfo(string strAttribute)
        {
            return webService.catalogProductAttributeInfo(this._sessionid, strAttribute);
        }
        public void RefreshCatalog()
        {
            webService.saasRefreshCatalog(this._sessionid);
        }

        private catalogProductAttributeMediaCreateEntity GetcatalogProductAttributeMediaCreateEntity(Image image, int iPosition, Product product)
        {

            var imageStream = new MemoryStream();
            image.Save(imageStream, ImageFormat.Jpeg);
            byte[] encbuff = imageStream.ToArray();
            string enc = Convert.ToBase64String(encbuff, 0, encbuff.Length);

            var imageEntity = new catalogProductImageFileEntity();
            imageEntity.content = enc;
            imageEntity.name = (GetProductName(product) + GetRandom(listFit) + product.SKU + iPosition).Replace(' ', '-').Replace('&', '-').Replace("'", "").Replace("@", "");
            imageEntity.mime = "image/jpeg";
            imageStream.Close();

            catalogProductAttributeMediaCreateEntity entityP = new catalogProductAttributeMediaCreateEntity();
            entityP.file = imageEntity;
            entityP.label = product.Feature + product.SKU + iPosition.ToString();
            if (iPosition == 0)
                entityP.types = new[] { "image", "small_image", "thumbnail" };
            entityP.exclude = "0";
            entityP.position = iPosition.ToString();
            return entityP;
        }

        private string GetProductName(Product product)
        {
            var strName = product.Feature.Replace(" 925 Sterling Silver Solid Core Charm", "").Replace(
                " 925 Sterling Silver Core Bead", "").Replace(" 925 Sterling Silver Bead", "").Replace(" 925 Sterling Silver", "").Replace(" fits Charm Troll", "").Replace(" Fits Charm Troll", "").Replace(" Fits Troll Charms", "").Replace(" Fits Troll", "").Replace(
                " Swarovski", "").Replace(" &amp;", "").Replace(" Authentic", "").Replace("Jewelry ", "");
            if (product.Type == "SnakeChain")
            {
                strName = strName + " Snake Chain Charm Starter Bracelets Bracelet";
                if (product.Material == "Sterling Silver")
                {
                    strName = strName + "  925 Sterling Silver " + product.Size + "mm";
                }
                else
                {
                    strName = strName + "  925 Sterling Silver " + product.Size + "mm";
                }
            }
            else
            {
                if (product.Material == "Sterling Silver")
                {
                    strName = strName + this.GetRandom(listAuthentic) + this.GetRandom(listSterlingSilver) + this.GetRandom(listBeads);
                }
                else
                {
                    strName = strName + this.GetRandom(listAuthentic) + this.GetRandom(listSterlingSilver) + this.GetRandom(listCore) + this.GetRandom(listBeads);
                }
            }
            return strName + " " +product.Theme;
        }

        private List<string> listAuthentic = new List<string>(){""," Authentic"};
        private List<string> listSterlingSilver = new List<string>(){""," 925 Sterling Silver"," Sterling Silver"};
        private List<string> listBeads = new List<string>() { "", " Bead", " Beads", " Charm", " Charms" };
        private List<string> listCore = new List<string>() { "", " Core", " Solid Core" };

        private List<string> listFit = new List<string>()
            {
                "",
                " Fits Pandora Charm",
                " Fits Pandora Charms",
                " Fits Pandora Charm Europen Style Bracelets",
                " Fits Pandora Charms Europen Style Bracelets",
                " Fits Pandora Bead",
                " Fits Pandora Beads",
                " Fits Pandora Bead Europen Style Bracelets",
                " Fits Pandora Beads Europen Style Bracelets",
                " Fits Chamilia Charm",
                " Fits Chamilia Charms",
                " Fits Chamilia Charm Europen Style Bracelets",
                " Fits Chamilia Charms Europen Style Bracelets",
                " Fits Chamilia Bead",
                " Fits Chamilia Beads",
                " Fits Chamilia Bead Europen Style Bracelets",
                " Fits Chamilia Beads Europen Style Bracelets",
                " Fits Biagi Charm",
                " Fits Biagi Charms",
                " Fits Biagi Charm Europen Style Bracelets",
                " Fits Biagi Charms Europen Style Bracelets",
                " Fits Biagi Bead",
                " Fits Biagi Beads",
                " Fits Biagi Bead Europen Style Bracelets",
                " Fits Biagi Beads Europen Style Bracelets",
            };
            
        private string GetRandom(List<string> list )
        {
            Random r = new Random(DateTime.Now.Millisecond);
            var i = r.Next(list.Count);
            return list[i];
        }


        private catalogProductCreateEntity GetcatalogProductCreateEntity(Product product)
        {
            catalogProductCreateEntity productData = new catalogProductCreateEntity();
            string title = GetProductName(product);
            string titleFit = title + GetRandom(listFit);
            if (titleFit.Length > 70)
            {
                titleFit = title;
            }
            productData.name = titleFit;
            //productData.url_key = productData.name;
            productData.visibility = "4";
            productData.status = "1";
            productData.weight = product.Weight;
            productData.price = product.Price.ToString(CultureInfo.InvariantCulture);
            productData.special_price = product.PriceSale.ToString(CultureInfo.InvariantCulture);
            productData.special_from_date = DateTime.Now.AddDays(-1).ToShortDateString();
            productData.special_to_date = DateTime.Now.AddDays(365).ToShortDateString();
            productData.short_description = GetShortDescription(product);
            productData.meta_title = title;
            productData.meta_keyword = product.Feature + "," + product.Color + "," + product.Material + "," + product.Metals + "," + product.Size + "," + product.Stone + "," + product.Theme + "," + product.Type + "," + product.Brand + "," + GetRandom(listFit);
            productData.meta_description = GetDescription(product);


            productData.description = GetShortDescription(product); 
            catalogInventoryStockItemUpdateEntity stock = new catalogInventoryStockItemUpdateEntity();
            stock.manage_stock = 1;
            if(product.EbaoInventory > 0)
                stock.is_in_stock = 1;
            else
                stock.is_in_stock = 0;
            stock.qty = Convert.ToString(product.EbaoInventory);
            productData.stock_data = stock;
            productData.tax_class_id = "Shipping";

            List<associativeEntity> listAssociativeEntity = new List<associativeEntity>();
            if (!string.IsNullOrEmpty(product.Stone))
            {
                var entity = GetStonesAssociativeEntity(product.Stone);
                if(entity!=null)
                    listAssociativeEntity.Add(entity);
            }
            if (!string.IsNullOrEmpty(product.Metals))
            {
                var entity = GetMetalsAssociativeEntity(product.Metals);
                if (entity != null)
                    listAssociativeEntity.Add(entity);
            }
            if (!string.IsNullOrEmpty(product.Material))
            {
                var entity = GetMaterialsAssociativeEntity(product.Material);
                if (entity != null)
                    listAssociativeEntity.Add(entity);
            }
            if (!string.IsNullOrEmpty(product.Theme))
            {
                var entity = GetThemesAssociativeEntity(product.Theme);
                if (entity != null)
                    listAssociativeEntity.Add(entity);
            }
            if (!string.IsNullOrEmpty(product.Color))
            {
                var entity = GetColorsAssociativeEntity(product.Color);
                if (entity != null)
                    listAssociativeEntity.Add(entity);
            }
            if (listAssociativeEntity.Count > 0)
            {
                productData.additional_attributes = new catalogProductAdditionalAttributesEntity();
                productData.additional_attributes.single_data = listAssociativeEntity.ToArray();
            }
            return productData;
        }

        private List<string> listDescCharms = new List<string>() { 
@"Ride the latest wave of European bead fashion jewelry with an exquisite (descriptive) polymer clay beads for your lampwork polymer clay beads bracelet. 
this bead is a great addition to your European bead bracelet or necklace. ", 
@"Ride the latest wave of European bead fashion jewelry with an exquisite (descriptive) polymer clay beads for your lampwork polymer clay beads bracelet. 
Create a traditional European beaded bracelet with many lampwork beads",
@"Ride the latest wave of European bead fashion jewelry with an exquisite (descriptive) polymer clay beads for your lampwork polymer clay beads bracelet. 
hang just one or two from a special lampwork polymer clay bead bracelet chain.",
@"Either way, your European beads bracelet will be a treasured addition to your jewelry collection.
Crafted and authenticated by Mai Bey, (descriptive) polymer clay Beads are available for both wholesale and retail purchase.
"};

        private List<string> listDescCharmsGlass = new List<string>()
            {
                @"Ride the latest wave of European bead fashion jewelry with an exquisite Mai Bey (descriptive) Glass European Bead for your lampwork glass beads bracelet. ",
                @"Fashioned of (descriptive) , this bead is a great addition to your European bead bracelet or necklace.Each bead is made by craftsmen working in a tradition that stretches back hundreds of years. ",
                @"Create a traditional European beaded bracelet with many lampwork glass beads, or hang just one or two from a special lampwork glass bead bracelet chain. ",
                @"Either way, your European beads bracelet will be a treasured addition to your jewelry collection. Crafted and authenticated by Mai Bey, (descriptive) Glass European Beads are available for both wholesale and retail purchase."

            };
        private List<string> listDescPendants = new List<string>()
            {
                @"Cute, dazzling and sophisticated, the (descriptive) Pendant is an excellent addition to your fashion ensemble.",
                @"Whether you use it to add spice to your dressier clothes, or dress up your casual outfits, this unique (descriptive) pendant is the perfect tool for the job. ",
                @"Like all pendants crafted and authenticated by Mai Bey, these (descriptive) Pendants are available for both wholesale and retail purchase.",
                @"Crafted with a keen eye to quality, design and fashion, a pendant is sure to make a long-lasting fashion impression on the people that matter the most. "
            };
        private List<string> listDescSafetyChains = new List<string>()
            {
                @"Cute, dazzling and sophisticated, the (descriptive) Pendant is an excellent addition to your fashion ensemble. ",
                @"Whether you use it to add spice to your dressier clothes, or dress up your casual outfits, this unique (descriptive) pendant is the perfect tool for the job. ",
                @"Like all pendants crafted and authenticated by Mai Bey, these (descriptive) Pendants are available for both wholesale and retail purchase."
            };
        private string GetDescription(Product product)
        {
            string template;
            string strDescription = null;
            if (product.Type == "Charms")
            {
                if (product.Material != "Glass")
                {
                    template = GetRandom(listDescCharms) + "Mai Bey 925 Sterling Silver jewelry designs bring glamour to your life and will be cherished always.";
                }
                else
                {
                    template = GetRandom(listDescCharmsGlass) + @"Mai Bey 925 Sterling Silver jewelry designs bring glamour to your life and will be cherished always.";
                }
                strDescription = template.Replace("(descriptive)", product.Feature);

            }
            else if (product.Type == "Pendants")
            {
                template = GetRandom(listDescPendants) + @"Mai Bey 925 Sterling Silver jewelry designs bring glamour to your life and will be cherished always.";
                strDescription = template.Replace("(descriptive)", product.Feature);
            }
            else if (product.Type == "Spacers")
            {
                template =
                    @"(descriptive) fits Pandora bracelets, made of 925 sterling silver. The perfect gift to the person you love on her/ his birthday. Compatible with Pandora Chamilia Trollbeads and Biagi.";
                strDescription = template.Replace("(descriptive)", product.Feature);
            }
            else if (product.Type == "Clips")
            {
                template =
                    @"Gorgeous and unique design (descriptive) 925 sterling silver clip lock charm.Beautiful high qulity silver, same on both sides.
Once it is clipped on the section it won't slide.For this charm you'll be able to open and clip into place anywhere along the bracelet chain without having to remove your other beads!";
                strDescription = template.Replace("(descriptive)", product.Feature);
            }
            else if (product.Type == "Safety-Chains")
            {
                template = GetRandom(listDescSafetyChains) + @"Mai Bey 925 Sterling Silver jewelry designs bring glamour to your life and will be cherished always.";
                strDescription = template.Replace("(descriptive)", product.Feature);
            }


            var strAdd = @"Measure: 4.5mm Core
Weight: " + product.Weight + @" Grams";
            if (product.Material == "Sterling Silver")
            {
                strAdd = strAdd + "\r\nMaterial: 925 Sterling Silver";
            }
            else
            {
                strAdd = strAdd + "\r\nMaterial: 925 Sterling Silver Core Bead";
            }
            return strAdd + "\r\n\r\n" + strDescription;
        }
        private string GetShortDescription(Product product)
        {

            string strAdd;
            if (product.Material == "Sterling Silver")
            {
                strAdd = "Material: 925 Sterling Silver";
            }
            else
            {
                strAdd = "Material: 925 Sterling Silver Core Bead";
            }
            strAdd = strAdd + @"  Weight: " + product.Weight + @"g";
            return strAdd;
        }

        private catalogProductAttributeEntity colorsCatalogProductAttributeEntity;
        private associativeEntity GetColorsAssociativeEntity(string color)
        {
            if (colorsCatalogProductAttributeEntity == null)
            {
                colorsCatalogProductAttributeEntity = GetAttributeInfo("color");
            }
            foreach (var catalogAttributeOptionEntity in colorsCatalogProductAttributeEntity.options)
            {
                if (catalogAttributeOptionEntity.label.ToUpper() == color.ToUpper())
                {
                    return new associativeEntity() { key = "color", value = catalogAttributeOptionEntity.value };
                }
            }
            return null;
        }
        

        private catalogProductAttributeEntity stonesCatalogProductAttributeEntity;
        private associativeEntity GetStonesAssociativeEntity(string store)
        {
            if (stonesCatalogProductAttributeEntity == null)
            {
                stonesCatalogProductAttributeEntity = GetAttributeInfo("stones");
            }
            foreach (var catalogAttributeOptionEntity in stonesCatalogProductAttributeEntity.options)
            {
                if (catalogAttributeOptionEntity.label.ToUpper() == store.ToUpper())
                {
                    return new associativeEntity() {key = "stones", value = catalogAttributeOptionEntity.value};
                }
            }
            return null;
        }
        private catalogProductAttributeEntity metalCatalogProductAttributeEntity;
        private associativeEntity GetMetalsAssociativeEntity(string metal)
        {
            if (metalCatalogProductAttributeEntity == null)
            {
                metalCatalogProductAttributeEntity = GetAttributeInfo("metals");
            }

            foreach (var catalogAttributeOptionEntity in metalCatalogProductAttributeEntity.options)
            {
                if (catalogAttributeOptionEntity.label.ToUpper() == metal.ToUpper())
                {
                    return new associativeEntity() { key = "metals", value = catalogAttributeOptionEntity.value };
                }
            }
            return null;
        }
        private catalogProductAttributeEntity materialsCatalogProductAttributeEntity;
        private associativeEntity GetMaterialsAssociativeEntity(string material)
        {
            if (materialsCatalogProductAttributeEntity == null)
            {
                materialsCatalogProductAttributeEntity = GetAttributeInfo("materials");
            }

            foreach (var catalogAttributeOptionEntity in materialsCatalogProductAttributeEntity.options)
            {
                if (catalogAttributeOptionEntity.label.ToUpper() == material.ToUpper())
                {
                    return new associativeEntity() { key = "materials", value = catalogAttributeOptionEntity.value };
                }
            }
            return null;
        }
        private catalogProductAttributeEntity themesCatalogProductAttributeEntity;
        private associativeEntity GetThemesAssociativeEntity(string theme)
        {
            if (themesCatalogProductAttributeEntity == null)
            {
                themesCatalogProductAttributeEntity = GetAttributeInfo("themes");
            }

            foreach (var catalogAttributeOptionEntity in themesCatalogProductAttributeEntity.options)
            {
                if (catalogAttributeOptionEntity.label.ToUpper() == theme.ToUpper())
                {
                    return new associativeEntity() { key = "themes", value = catalogAttributeOptionEntity.value };
                }
            }
            return null;
        }

        public void RemoveProductCrossSellLinks(string strSku)
        {
            var lsitLink = this.webService.catalogProductLinkList(this._sessionid, "cross_sell", strSku, null);
            foreach (var catalogProductLinkEntity in lsitLink)
            {
                this.webService.catalogProductLinkRemove(this._sessionid, "cross_sell", strSku,
                                                         catalogProductLinkEntity.sku, null);
            }
        }
        public void SetProductCrossSellLinks(string strSku, catalogProductEntity linkProduct)
        {
            var data = new catalogProductLinkEntity();
            data.position = "0";
            data.product_id = linkProduct.product_id;
            data.type = "cross_sell";
            data.sku = linkProduct.sku;
            this.webService.catalogProductLinkAssign(this._sessionid, "cross_sell", strSku, linkProduct.sku, data, null);
        }
        public void RemoveProductUpSellLinks(string strSku)
        {
            var lsitLink = this.webService.catalogProductLinkList(this._sessionid, "up_sell", strSku, null);
            foreach (var catalogProductLinkEntity in lsitLink)
            {
                this.webService.catalogProductLinkRemove(this._sessionid, "up_sell", strSku,
                                                         catalogProductLinkEntity.sku, null);
            }
        }
        public void SetProductUpSellLinks(string strSku, catalogProductEntity linkProduct)
        {
            var data = new catalogProductLinkEntity();
            data.position = "0";
            data.product_id = linkProduct.product_id;
            data.type = "up_sell";
            data.sku = linkProduct.sku;

            this.webService.catalogProductLinkAssign(this._sessionid, "up_sell", strSku, linkProduct.sku, data, null);
        }
    }
}
